﻿using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;

namespace BusStationClient
{      
    class ControlCard
    {
        private readonly SerialPort SerialPort = new SerialPort();
        /// <summary>
        /// 输入端口状态  正常下都为 1
        /// </summary>
        public string InPutState;
        /// <summary>
        /// 输出端口状态  0为关闭 1为开启
        /// </summary>
        public string OutPutState;

        public object obj;

        public ControlCard(string comport)
        {
            try
            {
                obj=new object();                
                SerialPort.PortName = comport;
                SerialPort.BaudRate = 9600;
                SerialPort.Open();
                SerialPort.DataReceived += SerialPortDataReceived;               
                Thread thread = new Thread(GetState) { IsBackground = true };
                thread.Start();            
            }
            catch (Exception ex)
            {                
                Common.LogService.WriteLog("控制卡串口开启失败.." + ex.Message);
            }
            
        }

        //获取各端口状态
        private void GetState()
        {
            byte[] cmd = GetStateInfoCommand();
            while (true)
            {
                SerialPort.Write(cmd, 0, cmd.Length);                
                Thread.Sleep(300);
            }
        }


        /// <summary>
        /// 设置输出端口的开关   
        /// </summary>
        /// <param name="cmd">0x01为打开 0x02为关闭  </param>
        /// <param name="port">端口号：1,2,3,4</param>
        /// <returns></returns>
        public void SetOutPutState(byte cmd, int port)
        {
            byte[] data = GetSetOutPutStateCommand(cmd, port);
            SerialPort.Write(data, 0, data.Length);
        }

        // 串口接收到的数据
        private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            try
            {
                byte[] readBuffer = new byte[SerialPort.BytesToRead];
                SerialPort.Read(readBuffer, 0, readBuffer.Length);
                string strReadBuffer = "";
                foreach (byte b in readBuffer)
                {
                    string s = Convert.ToString(b, 16);
                    if (s.Length == 1)
                    {
                        s = "0" + s;
                    }
                    strReadBuffer += "0x" + s + " ";
                }
                //Common.LogService.WriteLog("串口接收数据：" + strReadBuffer);
                if (CheckData(readBuffer))
                {

                    string strOut = Convert.ToString(readBuffer[2], 2).PadLeft(4, '0');
                    char[] charArrayOut = strOut.ToArray();
                    Array.Reverse(charArrayOut);
                    OutPutState = new string(charArrayOut);

                    string strIn = Convert.ToString(readBuffer[3], 2).PadLeft(4, '0');
                    char[] charArrayIn = strIn.ToArray();
                    Array.Reverse(charArrayIn);
                    InPutState = new string(charArrayIn);
                }
            }
            catch (Exception ex)
            {
                Common.LogService.WriteLog("控制卡接收数据处异常："+ex.Message);
            }          
        }



        // 获取设置输出端口开关的命令
        private byte[] GetSetOutPutStateCommand(byte cmd, int port)
        {
            List<byte> data = new List<byte>();
            data.Add(0x55);
            data.Add(cmd);
            byte number = 0x00;
            number = byte.Parse(Math.Pow(2, port - 1).ToString());
            data.Add(number);
            data.Add(0x00);
            byte count = 0x00;
            foreach (byte b in data)
            {
                count += b;
            }
            data.Add(count);
            return data.ToArray();
        }

        //查询各端口开关状态的命令
        private byte[] GetStateInfoCommand()
        {
            List<byte> data = new List<byte>();
            data.Add(0x55);
            data.Add(0x04);
            data.Add(0x00);
            data.Add(0x00);
            data.Add(0x59);
            Common.LogService.WriteLog("发送查询个端口状态命令...");
            return data.ToArray();
        }

        private bool CheckData(byte[] data)
        {
            if (data == null || data.Length != 5)
                return false;
            if (data[0] != 0x55 || data[1] != 0xF0)
                return false;
            byte count = 0;
            for (int i = 0; i < 4; i++)
            {
                count += data[i];
            }
            if (count != data[4])
                return false;
            return true;
        }
    }
}
